package com.zzq.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zzq.context.BaseContext;
import com.zzq.mapper.FileMapper;
import com.zzq.mapper.MessageMapper;
import com.zzq.mapper.TendererInfoMapper;
import com.zzq.pojo.FileDate;
import com.zzq.pojo.TenderInfo;
import com.zzq.pojo.dto.TenderInfoDTO;
import com.zzq.pojo.vo.FirstTenderInfo;
import com.zzq.pojo.vo.HotTenderInfo;
import com.zzq.pojo.vo.TenderInfoVO;
import com.zzq.pojo.vo.ViewCount;
import com.zzq.service.TendererInfoService;
import com.zzq.tools.HotTenderCalculator;
import com.zzq.tools.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class TendererInfoServiceImpl implements TendererInfoService {

    @Autowired
    private TendererInfoMapper tendererInfoMapper;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Value("${rocketmq-topic.bidding}")
    private String biddingTopic;

    @Value("${rocketmq-topic.inform}")
    private String informTopic;


//    // 获取自定义线程池
//    ExecutorService executor = ThreadPoolUtil.getExecutor();

    @Override
    public List<TenderInfoVO> all() {

        return tendererInfoMapper.all();

    }

    @Override
    public List<TenderInfo> some() {
        return tendererInfoMapper.some();
    }

    @Override
    @Transactional
    public void check(int no) {

        tendererInfoMapper.check(no);

        String name=tendererInfoMapper.getNameByNo(no);

        String message="【"+name+"】的投标项目【"+no+"】已审核通过。";
        // 异步发送并设置回调
        rocketMQTemplate.convertAndSend(
                informTopic + ":INFORM_TOPIC",
                message);

                log.info("通知发送成功: {}" ,message);
//        executor.submit(() -> {
//                // 异步执行数据库操作
//                String name=tendererInfoMapper.getNameByNo(no);
//                String message="【"+name+"】的投标项目【"+no+"】已审核通过。";
//                messageMapper.pushMessage(message);
//        });
    }

    @Override
    @Transactional
    public void elect(int no) {

        String name=tendererInfoMapper.getNameByNo(no);
        tendererInfoMapper.elect(no);
        fileMapper.deleteByBusinessId(no);

        String message="【"+name+"】的投标项目【"+no+"】由于不合规，审核不通过！请修改后重新提交。";

        rocketMQTemplate.convertAndSend(
                informTopic + ":INFORM_TOPIC",
                message);

        log.info("通知发送成功: {}" ,message);

//        executor.submit(() -> {
//                // 异步执行数据库操作
//                String message="【"+name+"】的投标项目【"+no+"】由于不合规，审核不通过！请修改后重新提交。";
//                messageMapper.pushMessage(message);
//        });
    }

    @Override
    @Transactional
    public void ourselfDelect(int no) {

        tendererInfoMapper.elect(no);
        fileMapper.elect(no);

    }

    @Override
    public List<TenderInfo> select(String manufacturer, String state) {
        return tendererInfoMapper.select(manufacturer, state);
    }

    @Override
    public List<TenderInfo> selectByName(String name) {
        return tendererInfoMapper.selectByName(name);
    }

    @Override
    @Transactional
    public void add(TenderInfoDTO tenderInfo) {
        tenderInfo.setState("待审核");
        TenderInfo t=TenderInfo.builder()
                .tenderProjectNo(tenderInfo.getTenderProjectNo())
                .drugName(tenderInfo.getDrugName())
                .manufacturer(tenderInfo.getManufacturer())
                .tenderDeadline(tenderInfo.getTenderDeadline())
                .bidDeposit(tenderInfo.getBidDeposit())
                .state(tenderInfo.getState())
                .totalNumber(tenderInfo.getTotalNumber())
                .packagingReq(tenderInfo.getPackagingReq())
                .build();

        FileDate fileDate=FileDate.builder()
                .fileUrl(tenderInfo.getFileId())
                .businessId(tenderInfo.getTenderProjectNo())
                .fileName(tenderInfo.getFileName())
                .fileSize(tenderInfo.getFileSize())
                .build();
        tendererInfoMapper.add(t);
        fileMapper.add(fileDate);
    }

    @Override
    public void update(TenderInfo tenderInfo) {
        tendererInfoMapper.update(tenderInfo);
    }

    @Override
    public List<TenderInfo> selectBid(String manufacturer) {
        return tendererInfoMapper.selectBid(manufacturer);
    }


    @Override
    public List<HotTenderInfo> getHotTenders(int page, int size) {
        String cacheKey = "hot_tenders_page_" + page + "_size_" + size;

        // 尝试从缓存获取
        List<HotTenderInfo> hotTenders = (List<HotTenderInfo>) redisTemplate.opsForValue().get(cacheKey);

        if (hotTenders == null) {
            // 缓存未命中，从数据库获取
            hotTenders = tendererInfoMapper.getHotTenders(page, size);

            // 获取当前时间并加上3天
            LocalDateTime threeDaysLater = LocalDateTime.now().plus(3, ChronoUnit.DAYS);

            for (HotTenderInfo hotTender : hotTenders) {
                // 获取原始的LinkedHashMap类型的截止日期
                LocalDateTime deadlineObj = hotTender.getTenderDeadline();

                // 判断截止日期是否小于当前时间的三天后
                boolean isBeforeThreeDaysLater = deadlineObj.isBefore(threeDaysLater);

                if (isBeforeThreeDaysLater) {
                    hotTender.setState("即将截止");
                } else {
                    hotTender.setState("进行中");
                }
            }
            // 放入缓存，设置5分钟过期
            redisTemplate.opsForValue().set(cacheKey, hotTenders, 5, TimeUnit.MINUTES);
        }

        return hotTenders;
    }

    /**
     * 记录项目浏览（带去重逻辑）
     * @param projectId 项目ID
     * @return 更新后的浏览数
     */
    @Override
    public void recordView(String projectId) {

        String VIEW_RECORD_KEY_PREFIX = "view:project:";
        Duration DEDUPLICATION_DURATION = Duration.ofHours(1);

        String userId= BaseContext.getCurrentId();

            // 1. 生成Redis键：view:project:{projectId}:{userId}
            String redisKey = VIEW_RECORD_KEY_PREFIX + projectId + ":user:" + userId;

            // 2. 使用Redis SETNX命令尝试设置键（原子操作）
            Boolean isNewView = redisTemplate.opsForValue()
                    .setIfAbsent(redisKey, "1", DEDUPLICATION_DURATION);

            // 3. 如果是新浏览，则更新数据库计数
            if (isNewView != null && isNewView) {
                ViewCount project = tendererInfoMapper.findViewCountById(projectId);
                        if(project==null){
                            throw new RuntimeException("项目不存在");
                        }

                int newViewCount = project.getViewCount()+ 1;
                        log.info("number{}",newViewCount);
                project.setViewCount(newViewCount);
                log.info("number:{}",project.getTenderProjectNo());
                log.info("name:{}",project.getViewCount());
                tendererInfoMapper.saveViewCount(project);
            }

        }

    @Override
    public List<FirstTenderInfo> gitfirstHotTendererInfo(int page, int size) {
        String cacheKey = "firstHot_tenders_page_" + page + "_size_" + size;

        // 尝试从缓存获取
        List<FirstTenderInfo> hotTenders = (List<FirstTenderInfo>) redisTemplate.opsForValue().get(cacheKey);

        if (hotTenders == null) {
            // 缓存未命中，从数据库获取
            hotTenders = tendererInfoMapper.gitfirstHotTendererInfo(page, size);

            // 放入缓存，设置5分钟过期
            redisTemplate.opsForValue().set(cacheKey, hotTenders, 5, TimeUnit.MINUTES);
            }


        return hotTenders;
    }

}
